package com.edais.service.imp;

import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.edais.dao.OptionDao;
import com.edais.dao.UserCardDao;
import com.edais.dao.UserDao;
import com.edais.domain.AppVersionInfo;
import com.edais.domain.Bank;
import com.edais.domain.PushSetting;
import com.edais.domain.User;
import com.edais.domain.UserInfo;
import com.edais.domain.UserRecePayCard;
import com.edais.domain.ViewFeedBack;
import com.edais.domain.sina.City;
import com.edais.domain.sina.Province;
import com.edais.mina.TcpMinaClient;
import com.edais.service.CenterService;
import com.edais.service.OptionService;
import com.edais.util.CommonUtil;
import com.edais.util.Consts;
import com.edais.util.JsonUtil;
import com.edais.util.ThirdPartyEnvUtil;
import com.edais.util.RSAThirdParty.RSA;
import com.edais.util.sina.ThridPartyFunctionUtil;

@Service

public class OptionServiceImp implements OptionService {
	private static final Log logger = LogFactory.getLog(OptionServiceImp.class);

	@Autowired
	private OptionDao optionDao;
	
	@Autowired
	private UserDao userDao;
	
	@Autowired
	private CenterService centerService;
	
	@Autowired
	private UserCardDao userCardDao;

	/**
	 * 绑定手机号
	 */
	@Override
	@Transactional
	public Map bindingPhone(String phoneNo, String id) throws Exception {
		/**
		 * 1:T_USER的SINA_IDCARD_VALIDATE修改成Y,同时修改user_info的手机号
		 * 2:调用sina接口绑定认证信息（成功事务提交，失败事务回滚）
		 * 3:修改主账号手机号
		 */
		Map<String,String> result = new HashMap<String,String>();
		User user = userDao.getUserDetail(id);
		// 在1.0版本中去除sina的绑定功能
		if("N".equals(user.getSina_idcard_validate())){
			Map<String,Object> map = new HashMap<String,Object>();
			map.put("mobile_validate", "Y");
			map.put("mobile", phoneNo);
//			map.put("sina_idcard_validate", "Y");
			map.put("userId",id);
			//修改手机号
			userDao.updUser(map);
			userDao.updUserInfo(map);
			
			//sina绑定认证信息
			/*Map<String,String> thridPartyParams = new HashMap<String,String>(); 
			//用户新浪对接用户ID 
			thridPartyParams.put("userId", user.getDeposit_dock_userid());
			//用户新浪对接用户类型
			thridPartyParams.put("verifyEntity", phoneNo);
			
			Map<String,String> bindingVerifyResult = ThridPartyFunctionUtil.bindingVerify(thridPartyParams);
			
			if(bindingVerifyResult ==null || "sysException".equals(bindingVerifyResult.get("rescode"))){
				logger.error("sina绑定认证失败:" + String.valueOf(bindingVerifyResult.get("resmsg_cn")));
				throw new RuntimeException("sina绑定认证失败");
			}else if("BusinessException".equals(bindingVerifyResult.get("rescode"))){
				logger.error("sina绑定认证失败:" + String.valueOf(bindingVerifyResult.get("resmsg_cn")));
				throw new RuntimeException(String.valueOf(bindingVerifyResult.get("resmsg_cn")));
			}*/
			
			if("1".equals(user.getIs_create_acct())){
				//更改核心主账户表
				//判断是否存在主账户
				/** 组织数据 */
				String transCode = "E300024";
				SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
				String sysdate = sdf.format(new Date());
				//设置报文体报文数据
				Map user_acc = new HashMap();
				user_acc.put("userid", String.valueOf(id));//用户id
				user_acc.put("mobilenum", phoneNo);//用户手机号
				user_acc.put("identitynum", "");//身份证号
				user_acc.put("useralias", "");//用户昵称
				user_acc.put("sysuserid", String.valueOf(id));//用户id
				user_acc.put("username", "");//用户名
				user_acc.put("email", "");//用户邮箱
				/**构建json字符串**/
				Map resmap = centerService.coreUse(String.valueOf(id),transCode,user_acc);
				if (resmap == null || !"00000".equals(resmap.get("rescode"))) {
					result.put("code", "00001");
					return result;
				}
			}
		}
		result.put("code", "00000");
		return result;
	}

	@Override
	public List<Bank> getBankDetail(Map<String,Object> map) throws Exception {
		// TODO Auto-generated method stub
		return this.optionDao.getBankDetail(map);
	}

	/**
	 * 根据应用版本号、操作系统获取该操作系统的版本更新的信息
	 * 
	 * @param appVersion
	 *            应用版本号
	 * @param osName
	 *            操作系统
	 * @return
	 * @throws Exception
	 */
	@Override
	public AppVersionInfo getAppVersionInfo(String appVersion, String osName)
			throws Exception {

		// 1 1 1.0.0 android 无需升级 1 AAAYE3AAHAAAItfAAA
		// 版本信息确认
		// 根据操作系统查询最新版本的信息
		AppVersionInfo appVersionInfoNew = this.optionDao
				.getAppVersionInfoNew(osName);
		// 如果数据库中没有记录，更新类型默认1-无需更新
		if (null == appVersionInfoNew) {
			appVersionInfoNew = new AppVersionInfo();
			appVersionInfoNew.setAppVersion("");
			appVersionInfoNew.setDownloadUrl("");
			appVersionInfoNew.setOsName(osName);
			appVersionInfoNew.setUpdateDesc("暂无版本");
			appVersionInfoNew.setUpdateType("1");// 更新类型：1-无需升级，2-可选升级,3-必须升级
			appVersionInfoNew.setInreview("0");
			appVersionInfoNew.setReadyforsale("1");
		} else {
			//数据库中有记录
			logger.info(osName + "当前最新的版本号是："+ appVersionInfoNew.getAppVersion());
			// 替换版本号
			Integer verNowInt = Integer.valueOf(CommonUtil.addZeroForNum(appVersion.replace(".", ""), 3));
			Integer verNewInt = Integer.valueOf(CommonUtil.addZeroForNum(appVersionInfoNew.getAppVersion().replace(".", ""),3));
			//如果上送版本号大于数据库中最新版本号，则更新类型置为1
			if (verNowInt >= verNewInt) {
				appVersionInfoNew.setUpdateType("1");// 更新类型：1-无需升级，2-可选升级,3-必须升级
				return appVersionInfoNew;
			}
			
			// 根据应用版本号、操作系统查询该版本的信息
			AppVersionInfo appVersionInfoCurrent = this.optionDao.getAppVersionInfoCurrent(appVersion, osName);
			
			//如果不存在请求的版本，则返回最新的版本信息
			if (null == appVersionInfoCurrent) {
				//appVersionInfoNew.setUpdateType("1");// 更新类型：1-无需升级，2-可选升级,3-必须升级
				return appVersionInfoNew;
			}
			// 如果存在请求的版本，则进行比较：相同的版本号，则更新类型为1
			if (appVersionInfoCurrent.getAppVersion().equals(
					appVersionInfoNew.getAppVersion())) {
				appVersionInfoNew.setUpdateType("1");// 更新类型：1-无需升级，2-可选升级,3-必须升级
			} else {
				// 不同的版本号，获取两个版本之间更新类型最大值：1-无需升级，2-可选升级,3-必须升级
				String updateType = this.optionDao.getAppVersionUpdateType(
						osName, appVersionInfoCurrent.getId(),
						appVersionInfoNew.getId());
				appVersionInfoNew.setUpdateType(updateType);// 更新类型：1-无需升级，2-可选升级,3-必须升级
			}
		}

		return appVersionInfoNew;
	}

	@Override
	public void insertView(ViewFeedBack viewMsg) throws Exception {
		this.optionDao.insertView(viewMsg);
	}
	
	/**
	 * 创建主账户
	 * @throws Exception
	 */
	public String createAccount(Map<String,Object> map,String userId) throws Exception{
		String useralias = "";
		String email = "";
		String phoneno = "";
		String transCode = "E300004";
		
		User user = userDao.getUserDetail(userId);
		if (user != null) {
			useralias = (null == user.getNick_name() ? "" : user.getNick_name());
//			useralias = user.getNick_name();
			email = (null == user.getEmail() ? "" : user.getEmail());
			phoneno = (null == user.getMobile() ? "" : user.getMobile());
		}

		// 设置报文体报文数据
		map.put("useralias", useralias);
		map.put("email", email);
		map.put("phoneno", phoneno);
		
		// 设置报文体报文数据
		String jsonStr = CommonUtil.constructJsonStr(transCode, userId, map);// 构建json字符串
		TcpMinaClient tcpMinaClient = new TcpMinaClient();
		String rtnStr = tcpMinaClient.sendMessage(jsonStr);

		if(StringUtils.isBlank(rtnStr)){
			logger.error("调用核心接口E300004发生异常");
			return "fail";
		}
		
		rtnStr = rtnStr.substring(8, rtnStr.length());
		// 转化json数据为页面模型数据格式
		Map rtnMap = (HashMap) JsonUtil.getObjectFromJsonString(rtnStr,HashMap.class);
		
		if (rtnMap == null || (!"00000".equals(rtnMap.get("rescode")) && !"user.identityno.has.registed".equals(rtnMap.get("resmsg")))) {
			logger.error("创建主账户E300004异常:" + rtnMap.get("resmsg"));
			return "fail";
		}
		return "success";
	}

	@Override
	public String getThemeId(String key) throws Exception {
		return optionDao.getThemeId(key);
	}

	@Override
	@Transactional
	public void setPushSwitchOn(String switchFlg1, String userId, String switchFlg2, String themeId) throws Exception {
		optionDao.setPushSwitchOn(switchFlg1, userId, switchFlg2, themeId);
	}

	@Override
	@Transactional
	public void setPushSwitchOff(String userId, String themeId, String switchFlg1, String switchFlg2) throws Exception {
		optionDao.setPushSwitchOff(userId, themeId, switchFlg1, switchFlg2);
	}

	@Override
	public List<PushSetting> getSettingStus(Map<String, Object> map) throws Exception {
		return optionDao.getSettingStus(map);
	}

	/**
	 * 取得省份和城市的基础数据 
	 */
	@Override
	public List<Province> getAreaData() throws Exception {
		// 省份
		List<Province> provinceList = optionDao.getProvinces();
		// 城市
		List<City> cityList = optionDao.getCitys();
		
		for(Province province : provinceList){
			List<City>  citys = new ArrayList<City>();
			for(City city : cityList){
				if(city.getProvinceId().equals(province.getProvinceId())){
					citys.add(city);
				}
			}
			province.setCityList(citys);
		}
		
		return provinceList;
		
	}
	
	/**
	 * 获取所有省份
	 */
	@Override
	public List<Province> getAllProvince() throws Exception {
		// 省份
		List<Province> provinceList = optionDao.getProvinces();
		return provinceList;
	}
	
	/**
	 * 获取全部城市信息
	 */
	@Override
	public List<City> getAllCity() throws Exception {
		List<City> cityList = optionDao.getCitys();
		return cityList;
	}
	
	/**
	 * 根据省份ID查询城市
	 */
	@Override
	public List<City> getCityListByProvinceId(String provinceId) throws Exception{
		List<City> cityList = this.optionDao.getCityByProvince(provinceId);
		return cityList;
	}

	/**
	 * 绑卡卡号预处理
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = false)
	public Map<String,String> setPayBankFirst(Map<String, String> map) throws Exception {
		UserInfo userInfo = userDao.getUserInfo(map.get("userId"));
		String certificateNo = userInfo.getId_card();
		String realName = userInfo.getReal_name();
		// 银行预留手机号
		String phoneno = map.get("phoneNo");
		// 获取省份名称
//		Province province = optionDao.getProvinceById(map.get("provinceId"));
		// 获取城市名称
//		City city = optionDao.getCityById(map.get("cityId"));
		// 银行编码
		map.put("platform_en_name", "ZHIFUTONGPAY");
		Bank bank = optionDao.getBankCodeById(map);
		
		// 保存卡记录，不过先设置成无效状态
//		String seq = createRequestNo();
		UserRecePayCard userRecePayCard = new UserRecePayCard();
//		userRecePayCard.setBinding_req_num(seq);
		userRecePayCard.setBank_id(Integer.valueOf(map.get("bankID")));//银行ID
		userRecePayCard.setBank_name(bank.getBank_name());//银行名称
		userRecePayCard.setUser_id(Integer.valueOf(map.get("userId")));//用户ID
		userRecePayCard.setIs_valid('Y');//是否可用（Y/N）
		userRecePayCard.setCard_number(map.get("bankCardNM"));//银行卡号
		userRecePayCard.setIs_binding('Y');//是否为现绑定回款号（Y/N）
		userRecePayCard.setPhone_no(phoneno);//预留手机号
		userRecePayCard.setAccount_name(realName);//开户名
		userRecePayCard.setReceive_certificate_type(1);//收款方证件类型(暂时只支持:身份证):1、省份证
		userRecePayCard.setReceive_certificate_no(certificateNo);//收款方证件预留号码
		userRecePayCard.setMedia_type(1);//媒介类型(暂时只支持:手机)：1、手机
		userRecePayCard.setCreate_per(map.get("userId"));//创建人
		userRecePayCard.setUpdate_per(map.get("userId"));//更新人
		userRecePayCard.setProvince(map.get("provinceId"));//开户省份
		userRecePayCard.setCity(map.get("cityId"));//开户城市
		optionDao.addPayCard(userRecePayCard);
		
		// 绑定银行卡
		/*UserRecePayCard userRecePayCard2 = optionDao.getBankCardId(userRecePayCard);
		Map<String,String> bindingParam = new HashMap<String,String>();
		bindingParam.put("request_no", seq);//绑卡请求号
		bindingParam.put("identity_id", map.get("deposit_dock_userid"));//用户标识信息
		bindingParam.put("bank_code", bank.getBank_code());//银行编号
		bindingParam.put("bank_account_no", map.get("bankCardNM"));//银行卡号
		bindingParam.put("account_name", realName);//户名
		bindingParam.put("cert_no", certificateNo);//证件号码
		bindingParam.put("phone_no", phoneno);//银行预留手机号
		bindingParam.put("province", province.getProvinceName());//省份
		bindingParam.put("city", city.getCityName());//城市
				
		// 请求参数封装
		String requestParam = "keyRandom=KEY_RANDOM";
		String publicKeyParam="";
		try {
			publicKeyParam = RSA.getPublick_Key_Encrypt(bindingParam);
			requestParam = requestParam.replace("KEY_RANDOM", URLEncoder.encode(publicKeyParam, "utf-8"));
		} catch (Exception e) {
			logger.debug("公钥加密串："+e);
		}
		
		
		//第三方工程请求url
		String url = ThirdPartyEnvUtil.getValue("bindingCardUrl");
		String bindingCardResult = CommonUtil.sendPostByHttp(url, requestParam);
		if( null == bindingCardResult ){
			logger.error("sina绑定银行卡失败");
			throw new RuntimeException("绑定银行卡失败");
		}else{
			//解析发送结果
			Map bindingCardResMap = JsonUtil.getMapFromJsonString(bindingCardResult);
			if(null == bindingCardResMap  || "sysException".equals(bindingCardResMap.get("rescode"))){
				// 系统异常
				logger.error("sina绑定银行卡失败:" + String.valueOf(bindingCardResMap.get("resmsg_cn")));
				throw new RuntimeException("绑定银行卡失败");
			}else if("BusinessException".equals(bindingCardResMap.get("rescode"))){
				// 业务异常，把错误信息提示给用户
				logger.error("sina绑定银行卡失败:" + String.valueOf(bindingCardResMap.get("resmsg_cn")));
				throw new RuntimeException(String.valueOf(bindingCardResMap.get("resmsg_cn")));
			}else{
				bindingCardResMap.put("requestNo", userRecePayCard2.getId()+"");
				return bindingCardResMap;
			}
		}*/
		return null;
	}

	/**
	 * 绑卡卡号推进处理
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = false)
	public void setPayBankSecond(Map<String, String> map) throws Exception {
		// 请求参数封装
//		String param = CommonUtil.getHttpParameterFromMap(map);
//		logger.debug("sina绑定银行卡推进请求参数："+param);
		
		String requestParam = "keyRandom=KEY_RANDOM";
		String publicKeyParam="";
		try {
			publicKeyParam = RSA.getPublick_Key_Encrypt(map);
			requestParam = requestParam.replace("KEY_RANDOM", URLEncoder.encode(publicKeyParam, "utf-8"));
		} catch (Exception e) {
			logger.debug("公钥加密串："+e);
		}
		
		//第三方工程请求url
		String url = ThirdPartyEnvUtil.getValue("bindingCardAdvanceUrl");
		String bindingCardAdvanceResult = CommonUtil.sendPostByHttp(url, requestParam);
		if( null == bindingCardAdvanceResult ){
			logger.error("sina绑定银行卡推进失败");
			throw new RuntimeException("绑定银行卡推进失败");
		}else{
			//解析发送结果
			Map bindingCardAdvanceResMap = JsonUtil.getMapFromJsonString(bindingCardAdvanceResult);
			if(null == bindingCardAdvanceResMap  || "sysException".equals(bindingCardAdvanceResMap.get("rescode"))){
				// 系统异常
				logger.error("sina绑定银行卡推进失败:" + String.valueOf(bindingCardAdvanceResMap.get("resmsg_cn")));
				throw new RuntimeException("绑定银行卡推进失败");
			}else if("BusinessException".equals(bindingCardAdvanceResMap.get("rescode"))){
				// 业务异常，把错误信息提示给用户
				logger.error("sina绑定银行卡推进失败:" + String.valueOf(bindingCardAdvanceResMap.get("resmsg_cn")));
				throw new RuntimeException(String.valueOf(bindingCardAdvanceResMap.get("resmsg_cn")));
			}else{
				map.put("card_id", String.valueOf(bindingCardAdvanceResMap.get("card_id")));
			}
		}
				
		// 推进处理
		/*Map<String,String> resultMap = new SinaHostingFuntions().bindingBankCardAdvance(map);
		if(!"APPLY_SUCCESS".equals(resultMap.get("code"))){
			logger.error("sina绑定银行卡推进失败");
			throw new RuntimeException(resultMap.get("message"));
		}
		
		map.put("card_id", resultMap.get("card_id"));*/
		// 更改卡状态
		optionDao.updateBankCardInfo(map);
	}
	
	/**
	 * 新浪绑卡请求号生成
	 * @return
	 */
	public String createRequestNo() throws Exception{
		Date now = new Date();
		SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
		String currTime = outFormat.format(now);

		String requestNo = "HB" + optionDao.getSinaBindingReqSeqSeq() + currTime;
		return requestNo;
	}

	/**
	 * 更新支付密码
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = false)
	public void modifyPayPwd(Map<String, String> map) throws Exception {
		optionDao.modifyPayPwd(map);
	}

	/**
	 * 解绑手机号
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, readOnly = false)
	public Map unBindingPhone(String phoneNo, String id) throws Exception {
		/**
		 * 1:T_USER的SINA_IDCARD_VALIDATE修改成N
		 * 2:调用sina接口解绑（成功事务提交，失败事务回滚）
		 */
		Map<String,String> result = new HashMap<String,String>();
		User user = userDao.getUserDetail(id);
		
		if("Y".equals(user.getSina_idcard_validate())){
			Map<String,Object> map = new HashMap<String,Object>();
			map.put("sinaIdcardValidate", "N");
			map.put("userId", id);
			userDao.updSinaIdcardValidate(map);

			//解绑认证信息
			Map<String,String> thridPartyParams = new HashMap<String,String>(); 
			//用户新浪对接用户ID 
			thridPartyParams.put("identity_id", user.getDeposit_dock_userid());
			//用户新浪对接用户类型
			thridPartyParams.put("verify_type", "MOBILE");
			
			Map<String,String> unBindingVerifyResult = ThridPartyFunctionUtil.unBindingVerify(thridPartyParams);
			if(unBindingVerifyResult ==null || "sysException".equals(unBindingVerifyResult.get("rescode"))){
				logger.error("sina解绑认证失败:" + String.valueOf(unBindingVerifyResult.get("resmsg_cn")));
				throw new RuntimeException("sina解绑认证失败");
			}else if("BusinessException".equals(unBindingVerifyResult.get("rescode"))){
				logger.error("sina解绑认证失败:" + String.valueOf(unBindingVerifyResult.get("resmsg_cn")));
				throw new RuntimeException(String.valueOf(unBindingVerifyResult.get("resmsg_cn")));
			}
		}
		result.put("code", "00000");
		return result;
	}
	

	/**
	 * 借款申请主处理
	 */
	@Override
	@Transactional
	public String addLoanApplication(Map<String, String> map) throws Exception {
		
		optionDao.addLoanApplication(map);
		
		String result = CommonUtil.setResultStringCn(new HashMap<String,Object>(),
				Consts.SUCCESS_CODE, Consts.SUCCESS_DESCRIBE,"");
		
		return result;
	}
	
	/**
	 * 判断是否需要输入省份城市信息
	 */
	@Override
	public boolean withdrawNeedProvinceAndCity(String userId) throws Exception {
		// TODO Auto-generated method stub
		
		Map<String,Object> requestMap = new HashMap<String,Object>();
		requestMap.put("userId", userId);
		List<UserRecePayCard> cardList = this.userCardDao
				.queryUserCardInfoByUserId(requestMap);
		
		if(cardList==null || cardList.size()==0){
			return true;
		}
		UserRecePayCard userCard = cardList.get(0);
		requestMap.put("bankId", userCard.getBank_id());
		Bank bank =  this.userCardDao.queryBankInfoByBankCodeAndEanble(requestMap);
		boolean needProvinceAndCity = true;
		//判断银行是否需要省份城市信息
		
		if(bank!=null&&"N".equals(bank.getNeedprovinceandcity())){
			needProvinceAndCity = false;
		}else{
			//判断用户是否填写过省份城市信息
			if(StringUtils.isNotBlank(userCard.getProvince())&&StringUtils.isNotBlank(userCard.getCity())){
				needProvinceAndCity = false;
			}
		}
		
		return needProvinceAndCity;
	}
	
	@Override
	public City getCityByCode(String cityCode) {
		return this.optionDao.getCityByCode(cityCode);
	}
}
